package com.csweimei.rentmanagementtreasure.base;

import android.annotation.SuppressLint;
import android.app.Application;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.csweimei.rentmanagementtreasure.enterprise.viewModel.BuyCodeVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.CodeListVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.CustomerCenterVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.DealHouseVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.EntAuthVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.EntDayPaperVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.EntHouseDetailVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.GiftCodeVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.HomeEntVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.HouseInfoEntVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.JoinListVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.StaffDetailVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.StaffManagerVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.VipVM;
import com.csweimei.rentmanagementtreasure.enterprise.viewModel.WorkScheduleVM;
import com.csweimei.rentmanagementtreasure.http.Injection;
import com.csweimei.rentmanagementtreasure.http.Repository;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AboutVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddCustomerVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddDPVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddFollowVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddHouseFVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddHouseHzVm;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddHouseVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddRecordVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddZyHouseVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AddZyVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.AutoVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.ChooseCustomerVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.CustomVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.CustomerInfoVm;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.CustomerVm;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.DayPaperVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.FFourVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.FOneVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.FThreeVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.FTwoVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.FollowHouseVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.FollowRecordVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.HouseDetailHzVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.HouseDetailZzVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.HouseFRVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.HouseInfoVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.HzZyVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.JoinTeamVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.LeaseDVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.MLeaseVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.MessInfoVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.NoticeHouseVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.NoticeMessVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.PersonInfoVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.SearchTeamVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.SetVM;
import com.csweimei.rentmanagementtreasure.tenant.viewModel.VipPersonVM;
import com.csweimei.rentmanagementtreasure.viewModel.LoginVM;
import com.csweimei.rentmanagementtreasure.viewModel.MainVm;
import com.csweimei.rentmanagementtreasure.viewModel.SplashVM;

public class AppViewModelFactory extends ViewModelProvider.NewInstanceFactory {

    @SuppressLint("StaticFieldLeak")
    private static volatile AppViewModelFactory INSTANCE;
    private final Application mApplication;
    private final Repository mRepository;


    public static AppViewModelFactory getInstance(Application application) {
        if (INSTANCE == null) {
            synchronized (AppViewModelFactory.class) {
                if (INSTANCE == null) {
                    INSTANCE = new AppViewModelFactory(application, Injection.provideRepository());
                }
            }
        }
        return INSTANCE;
    }

    @VisibleForTesting
    public static void destroyInstance() {
        INSTANCE = null;
    }

    private AppViewModelFactory(Application application, Repository repository) {
        this.mApplication = application;
        this.mRepository = repository;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (modelClass.isAssignableFrom(LoginVM.class)) {
            return (T) new LoginVM(mApplication, mRepository);
        } else if (modelClass.isAssignableFrom(MainVm.class)) {
            return (T) new MainVm(mApplication, mRepository);
        } else if (modelClass.isAssignableFrom(FFourVM.class)) {
            return (T) new FFourVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(SplashVM.class)) {
            return (T) new SplashVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(PersonInfoVM.class)) {
            return (T) new PersonInfoVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(SetVM.class)) {
            return (T) new SetVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AboutVM.class)) {
            return (T) new AboutVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(FOneVM.class)) {
            return (T) new FOneVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(HouseInfoVM.class)) {
            return (T) new HouseInfoVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddHouseVM.class)) {
            return (T) new AddHouseVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(FollowRecordVM.class)) {
            return (T) new FollowRecordVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(HouseFRVM.class)) {
            return (T) new HouseFRVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddHouseFVM.class)) {
            return (T) new AddHouseFVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(ChooseCustomerVM.class)) {
            return (T) new ChooseCustomerVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddCustomerVM.class)) {
            return (T) new AddCustomerVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(CustomerVm.class)) {
            return (T) new CustomerVm(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(CustomerInfoVm.class)) {
            return (T) new CustomerInfoVm(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddRecordVM.class)) {
            return (T) new AddRecordVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AutoVM.class)) {
            return (T) new AutoVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddZyVM.class)) {
            return (T) new AddZyVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddZyHouseVM.class)) {
            return (T) new AddZyHouseVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(HouseDetailZzVM.class)) {
            return (T) new HouseDetailZzVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(MLeaseVM.class)) {
            return (T) new MLeaseVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(LeaseDVM.class)) {
            return (T) new LeaseDVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddHouseHzVm.class)) {
            return (T) new AddHouseHzVm(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(HouseDetailHzVM.class)) {
            return (T) new HouseDetailHzVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(HzZyVM.class)) {
            return (T) new HzZyVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(NoticeMessVM.class)) {
            return (T) new NoticeMessVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(NoticeHouseVM.class)) {
            return (T) new NoticeHouseVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(FTwoVM.class)) {
            return (T) new FTwoVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(FollowHouseVM.class)) {
            return (T) new FollowHouseVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddFollowVM.class)) {
            return (T) new AddFollowVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(CustomVM.class)) {
            return (T) new CustomVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(FThreeVM.class)) {
            return (T) new FThreeVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(MessInfoVM.class)) {
            return (T) new MessInfoVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(SearchTeamVM.class)) {
            return (T) new SearchTeamVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(JoinTeamVM.class)) {
            return (T) new JoinTeamVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(DayPaperVM.class)) {
            return (T) new DayPaperVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(AddDPVM.class)) {
            return (T) new AddDPVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(EntAuthVM.class)) {
            return (T) new EntAuthVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(HomeEntVM.class)) {
            return (T) new HomeEntVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(JoinListVM.class)) {
            return (T) new JoinListVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(HouseInfoEntVM.class)) {
            return (T) new HouseInfoEntVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(EntHouseDetailVM.class)) {
            return (T) new EntHouseDetailVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(CustomerCenterVM.class)) {
            return (T) new CustomerCenterVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(StaffManagerVM.class)) {
            return (T) new StaffManagerVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(StaffDetailVM.class)) {
            return (T) new StaffDetailVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(DealHouseVM.class)) {
            return (T) new DealHouseVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(WorkScheduleVM.class)) {
            return (T) new WorkScheduleVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(EntDayPaperVM.class)) {
            return (T) new EntDayPaperVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(VipVM.class)) {
            return (T) new VipVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(BuyCodeVM.class)) {
            return (T) new BuyCodeVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(GiftCodeVM.class)) {
            return (T) new GiftCodeVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(CodeListVM.class)) {
            return (T) new CodeListVM(mApplication, mRepository);
        }else if (modelClass.isAssignableFrom(VipPersonVM.class)) {
            return (T) new VipPersonVM(mApplication, mRepository);
        }
        throw new IllegalArgumentException("Unknown ViewModel class: " + modelClass.getName());
    }
}
